package com.gitee.feizns.quickstart.dict;

import com.gitee.feizns.dynamic.Lists;
import com.gitee.feizns.dynamic.Ref;
import com.gitee.feizns.quickstart.jackson.Val;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * dict （字典）
 * @author feizns
 * @since 2024/12/8
 */
public abstract class Dict {

    /**
     * dict 存储管理器
     */
    @SuppressWarnings("rawtypes")
    public static final Ref<DictDepositor> Depositor = new Ref<>(new ConcurrentHashMapDictDepositor<>());

    /**
     * 将整个字典作为Json值其格式如下：
     * <pre>{@code
     *  {
     *      'key':{
     *          'key':'key',
     *          'value': value,
     *          'permission':'ReadWrite'
     *      }
     *  }
     * }</pre>
     * @return {@link Val}
     */
    public static Val value() {
        return Depositor.get().value();
    }

    /**
     * 值
     * @param key 键
     * @return {@link Val}
     */
    public static Val value(String key) {
        return Depositor.get().value(key);
    }

    /**
     * 所有条目Map
     * @return {@link Map}<{@link String}, {@link Entry}>
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> entries() {
        return Depositor.get().entries();
    }

    /**
     * 条目列表
     * @return {@link List}<{@link Entry}>
     */
    @SuppressWarnings("unchecked")
    public static List<Entry> list() {
        return (List<Entry>) Depositor.get().list();
    }

    /**
     * 获取
     * @param key 键
     * @return {@link Entry}
     */
    public static Entry get(String key) {
        return Depositor.get().get(key);
    }

    /**
     * 放置字典条目
     * @param entry 值
     * @return {@link Entry}
     */
    @SuppressWarnings("unchecked")
    public static <T extends Entry> T put(T entry) {
        Entry e = get(entry.getKey());
        if ( e != null && e.getPermission() == Permission.ReadOnly )
            throw new UnsupportedOperationException(String.format("字典条目[%s]不支持修改.", entry.getKey()));
        Depositor.get().put(entry);
        return entry;
    }

    /**
     * 放置字典条目
     * @param entries 条目列表
     * @return {@link Entry[]}
     */
    @SafeVarargs
    public static <T extends Entry> List<T> put(T... entries) {
        return put(Lists.of(entries));
    }

    /**
     * 放置字典条目
     * @param entries 条目列表
     * @return {@link Entry[]}
     */
    public static <T extends Entry, U extends Collection<T>> List<T> put(U entries) {
        return putAll(entries);
    }

    /**
     * 放置字典条目
     * @param entries 条目列表
     * @return {@link Entry[]}
     */
    public static <T extends Entry, U extends Collection<T>> List<T> putAll(U entries) {
        return entries.stream().map(Dict::put).collect(Collectors.toList());
    }

    /**
     * 包含字典
     * @param key 字典键
     * @return 是否存在
     */
    public static boolean exists(String key) {
        return Depositor.get().exists(key);
    }

    /**
     * 删除
     * @param key 钥匙
     * @return {@link Entry }
     */
    public static Entry delete(String key) {
        Entry e = get(key);
        if ( e != null ) {
            if ( e.getPermission() == Permission.ReadOnly )
                throw new UnsupportedOperationException(String.format("字典条目[%s]不支持删除.", key));
            return Depositor.get().delete(key);
        }
        return null;
    }

    /**
     * 如果不存在，则放
     */
    public static void putIfAbsent(String key, Entry entry) {
        if ( !Dict.exists(key) )
            Dict.put(entry);
    }

    /**
     * 如果不存在，则获取 put
     * @param key 钥匙
     * @param entry 进入
     * @return {@link Entry }
     */
    public static Entry getIfAbsentPut(String key, Entry entry) {
        Entry e = Dict.get(key);
        if ( e == null ) {
            Dict.put(entry);
            e = entry;
        }
        return e;
    }

}
